# +----------------------------------------------------------------------
# | ChatWork智能聊天办公系统
# +----------------------------------------------------------------------
# | 软件声明: 本系统并非自由软件,未经授权任何形式的商业使用均属非法。
# | 版权保护: 任何企业和个人不允许对程序代码以任何形式任何目的复制/分发。
# | 授权要求: 如有商业使用需求,请务必先与版权所有者取得联系并获得正式授权。
# +----------------------------------------------------------------------
# | Author: ChatWork Team <2474369941@qq.com>
# +----------------------------------------------------------------------
from decimal import Decimal
from typing import List, Union
from fastapi import Query
from pydantic import BaseModel, Field


class UserWalletSearchIn(BaseModel):
    """ 钱包日志搜索参数 """
    page_no: int = Query(gt=0, default=1, description="当前页码")
    page_size: int = Query(gt=0, default=15, description="每页条数")
    scene: Union[str, None] = Query(default="points", description="场景: [points,train,robot,know,other]")
    change_type: Union[int, str, None] = Query(default=None, description="变动类型")
    start_time: Union[int, str, None] = Query(default=None, description="开始时间")
    end_time: Union[int, str, None] = Query(default=None, description="结束时间")


class UserEditIn(BaseModel):
    """ 编辑信息参数 """
    field: str = Field(..., min_length=1, max_length=100, description="键")
    value: str = Field(..., min_length=1, max_length=300, description="值")

    class Config:
        json_schema_extra = {
            "example": {
                "field": "account",
                "value": "wait"
            }
        }

    @classmethod
    def messages(cls):
        return {
            "field.min_length": "请填写要修改的字段",
            "field.max_length": "填写的字段名称异常",
            "value.min_length": "请填写对应字段需修改的值",
            "value.max_length": "修改的值不能超300个字符"
        }


class UserForgetPwdIn(BaseModel):
    """ 忘记密码参数 """
    scene: str = Field(min_length=1, max_length=20, description="场景: [mobile,email]")
    code: str = Field(min_length=6, max_length=20, description="验证码")
    account: str = Field(min_length=1, description="手机号/邮箱号")
    password: str = Field(min_length=6, max_length=20, description="新密码")

    class Config:
        json_schema_extra = {
            "example": {
                "scene": "mobile",
                "account": "13800138000",
                "password": "123456",
                "code": "628455"
            }
        }

    @classmethod
    def messages(cls):
        return {
            "mobile.min_length": "请填写手机号",
            "mobile.pattern": "手机号格式不正确",
            "password.min_length": "新密码不能少于6个字符",
            "password.max_length": "新密码不能大于20个字符",
            "code.min_length": "验证码错误",
            "code.max_length": "验证码错误"
        }


class UserChangePwdIn(BaseModel):
    """ 修改密码参数 """
    old_pwd: str = Field(min_length=6, max_length=20, description="旧密码")
    new_pwd: str = Field(min_length=6, max_length=20, description="新密码")

    class Config:
        json_schema_extra = {
            "example": {
                "old_pwd": "123456",
                "new_pwd": "123457"
            }
        }

    @classmethod
    def messages(cls):
        return {
            "old_pwd.min_length": "旧密码错误",
            "old_pwd.max_length": "旧密码错误",
            "new_pwd.min_length": "新密码不能少于6个字符",
            "new_pwd.max_length": "新密码不能大于20个字符",
        }


class UserBindMobileIn(BaseModel):
    """ 绑定手机参数 """
    scene: str = Field(min_length=1, description="场景: [change,bind]")
    mobile: str = Field(min_length=1, pattern=r"^(1[3-9]\d{9})?$", description="手机号")
    code: str = Field(min_length=6, max_length=20, description="验证码")

    class Config:
        json_schema_extra = {
            "example": {
                "scene": "change",
                "mobile": "13800138000",
                "code": "628455"
            }
        }

    @classmethod
    def messages(cls):
        return {
            "scene.min_length": "绑定场景缺失: [change,bind]",
            "mobile.min_length": "请填写手机号",
            "mobile.pattern": "手机号格式不正确",
            "code.min_length": "验证码错误",
            "code.max_length": "验证码错误"
        }


class UserBindEmailIn(BaseModel):
    """ 绑定邮箱参数 """
    scene: str = Field(min_length=1, description="场景: [change,bind]")
    email: str = Field(min_length=1, description="邮箱号: [change,bind]")
    code: str = Field(min_length=4, max_length=20, description="验证码")

    class Config:
        json_schema_extra = {
            "example": {
                "scene": "change",
                "email": "wait@163.com",
                "code": "628455"
            }
        }

    @classmethod
    def messages(cls):
        return {
            "scene.min_length": "绑定场景缺失: [change,bind]",
            "email.min_length": "请填写邮箱号",
            "email.pattern": "邮箱号格式不正确",
            "code.min_length": "验证码错误",
            "code.max_length": "验证码错误"
        }


class UserBindWechatIn(BaseModel):
    """ 绑定微信参数 """
    state: str = Field(default="", max_length=200, description="公众号盐,小程序是不需要")
    code: str = Field(..., min_length=1, max_length=64, description="微信Code")

    class Config:
        json_schema_extra = {
            "example": {
                "state": "27ab37b88696IflB",
                "code": "8b60a349771bdEb813e627ab37b88696IflBgj"
            }
        }

    @classmethod
    def messages(cls):
        return {
            "state.max_length": "state参数异常",
            "code.min_length": "code微信参数错误",
            "code.max_length": "code微信参数错误"
        }


"""--------------- Separator ---------------"""


class UserCenterVo(BaseModel):
    """ 个人中心Vo """
    class Subscribe(BaseModel):
        id: int = Field(description="套餐ID")
        name: str = Field(description="套餐名称")
        end_time: str = Field(description="到期时间")
        is_builtin: bool = Field(description="系统内置")
        is_overdue: bool = Field(description="是否到期")
        is_perpetual: bool = Field(description="是否永久会员")

    id: int = Field(description="用户ID")
    sn: str = Field(description="用户编号")
    account: str = Field(description="用户账号")
    nickname: str = Field(description="用户名称")
    avatar: str = Field(description="用户头像")
    mobile: str = Field(description="手机号码")
    email: str = Field(description="电子邮箱")
    points: int = Field(description="剩余积分")
    train_num: int = Field(description="训练组数")
    robot_num: int = Field(description="智能体数")
    know_num: int = Field(description="知识库数")
    gender: int = Field(default=0, description="用户性别: [0=未知, 1=男, 2=女]")
    is_wechat: int = Field(default=0, description="已绑微信: [0=否, 1=是]")
    is_password: int = Field(default=0, description="已设密码: [0=否, 1=是]")
    create_time: str = Field(default="", description="注册时间")
    last_login_time: str = Field(default="", description="最后登录时间")
    subscribe: Subscribe = Field(description="订阅信息")

    class Config:
        json_schema_extra = {
            "example": {
                "id": 1,
                "sn": "38604409",
                "account": "wait",
                "nickname": "u38604409",
                "avatar": "https://wa.com/static/avatar.png",
                "mobile": "13800138000",
                "email": "13800@163.com",
                "points": 10,
                "train_num": 10,
                "robot_num": 10,
                "know_num": 10,
                "gender": 0,
                "is_wechat": 0,
                "is_password": 0,
                "create_time": "2023-12-20 11:27:05",
                "last_login_time": "2023-12-20 11:27:05",
                "subscribe": {
                    "name": "基础版",
                    "end_time": "2024-12-09 23:20:04",
                    "is_overdue": False
                }
            }
        }


class UserWalletLogsVo(BaseModel):
    """ 钱包日志Vo """
    log_sn: str = Field(description="日志编号")
    action: int = Field(description="变动类型: [1=增加, 2=减少]")
    project: str = Field(description="项目名称")
    change_type: str = Field(description="变动类型")
    change_amount: Decimal = Field(max_digits=15, decimal_places=7, default=0, description="变动数量")
    create_time: str = Field(description="记录时间")
    additional: List[dict] = Field(description="附加信息")

    class Config:
        json_schema_extra = {
            "example": {
                "log_sn": "2024612036885987442",
                "action": 1,
                "project": "校园机器人",
                "change_type": "对话消耗",
                "change_amount": 0.01,
                "create_time": "2024-07-20 01:26:18",
                "additional": [
                    {
                        "name": "chat",
                        "model": "gpt-4o",
                        "str_length": 16,
                        "total_price": 0.16,
                        "total_tokens": 33,
                        "prompt_tokens": 4,
                        "completion_tokens": 29
                    }
                ]
            }
        }


class UserQuotaInfoVo(BaseModel):
    """ 用户配额详细Vo """
    class Quota(BaseModel):
        pack_num: int = Field(description="订阅额度")
        user_num: int = Field(description="用户额度")
        total_num: int = Field(description="合计额度")
        usage_num: int = Field(description="消耗额度")
        surplus_num: int = Field(description="剩余额度")

    points: int = Field(description="剩余积分数")
    mcp: Quota = Field(description="MCP配额")
    know: Quota = Field(description="知识库配额")
    robot: Quota = Field(description="智能体配额")
    train: Quota = Field(description="训练组配额")

    class Config:
        json_schema_extra = {
            "example": {
                "points": 567,
                "mcp": {
                    "pack_num": 20,
                    "user_num": 0,
                    "total_num": 20,
                    "usage_num": 1,
                    "surplus_num": 19
                },
                "know": {
                    "pack_num": 20,
                    "user_num": 0,
                    "total_num": 20,
                    "usage_num": 1,
                    "surplus_num": 19
                },
                "robot": {
                    "pack_num": 10,
                    "user_num": 0,
                    "total_num": 10,
                    "usage_num": 1,
                    "surplus_num": 19
                },
                "train": {
                    "pack_num": 5000,
                    "user_num": 0,
                    "total_num": 5000,
                    "usage_num": 0,
                    "surplus_num": 5000
                }
            }
        }
